
在C++中为数据并行编程与并行相关，并行编程的目标是更快地计算。结果表明，这有两个方面优点:增加吞吐量和减少延迟。\par

\hspace*{\fill} \par %插入空行
\textbf{吞吐量}

当在规定的时间内完成更多的工作时，吞吐量就会增加。像流水线这样的技术实际上可能会延长完成单个工作项目所需的时间，允许工作的重叠，从而让更多的工作在单位时间内完成。人们在一起工作时经常遇到这种情况，共享就涉及到协调的开销，这往往会减慢完成工作的时间。然而，多人的力量会带来更多的吞吐量。计算机也不例外——将工作扩展到更多的处理核芯中，会给每个工作单元增加开销，这可能会导致一些延迟，因为有更多的处理核芯可以一起工作，所以可以完成更多的工作。\par

\hspace*{\fill} \par %插入空行
\textbf{延迟}

如果想要更快地完成一件事，例如：分析语音命令并形成的反应，该怎么办?如果只关心吞吐量，那么响应时间可能会增加到无法忍受的程度。减少延迟要求我们将一项工作分解成可以并行处理的模式。对于吞吐量，图像处理可能会将整个图像分配给不同的处理单元——这种情况下，目标可能是优化每秒的图像数。对于延迟，图像处理可能会将图像中的每个像素分配给不同的处理核芯——目标是最大化处理单个图像的每秒像素。\par

\hspace*{\fill} \par %插入空行
\textbf{并行思维}

并行开发者在编程中，会使用这两种技术。\par

想要调整思维，首先思考在算法和应用中，并行在哪里可行。还要考虑表达并行性的不同方式，以及如何影响最终性能。这么多东西需要去理解，所以并行思维是并行开发者一生的追求。这里可以学习一些技巧。\par

\hspace*{\fill} \par %插入空行
\textbf{Amdahl和Gustafson}

在1967年，由超级计算机先驱吉恩·阿姆达尔(Gene Amdahl)提出的阿姆达尔定律(Amdahl’s Law)是一个公式，用来预测使用多处理器时理论上的最大速度。Amdahl遗憾地说，并行的最大收益被限制在$\frac{1}{1+p}$，其中p是并行运行的程序的部分。如果只并行运行程序的三分之二，那么最多可以加速3倍。当然要深入理解这个概念!这是因为不管让三分之二的程序以多快的速度运行，其他三分之一仍然需要相同的时间来完成。即使增加100个GPU，也只能得到3倍的性能提升。\par

许多年来，有些人认为这证明了并行计算的不可行性。1988年，John Gustafson发表了一篇题为“重新评估Amdahl定律”的文章。他注意到并行不是用来加速定量的工作，而是用来扩展的。大家也有同样的生活经历，1个快递员无法在更多的人和卡车的帮助下更快地递送1个包裹。然而，100个人和100辆卡车运送100件包裹比1个司机开着1辆卡车要快得多。多个司机肯定会增加吞吐量，通常也会减少交付的延迟。Amdahl定律告诉我们，1个司机不能通过增加99个司机，用1辆卡车更快地递送1个包裹。Gustafson注意到，有了这些额外的司机和卡车，可以更快地递送100个包裹。\par

\hspace*{\fill} \par %插入空行
\textbf{可扩展性}

“可扩展性”一词在之前的讨论中出现过。可扩展性是衡量附加计算可用时程序加速的程度(简单地称为“加速”)。如果100个包裹与1个包裹同时运送，只需用100辆卡车和司机(而不是1辆卡车和1个司机)，就可以实现加速。当然，存在限制加速的瓶颈。配送中心可能没有100个地方可以让卡车停靠。计算机程序中，瓶颈经常涉及到将数据移到将要处理的地方。分发到100个卡车类似于必须将数据分发到100个处理核心，且分发需要时间。第3章会探索如何将数据分发到异构系统需要的地方。数据分发是有成本的，而该成本会影响对应用可扩展性的预期。\par

\hspace*{\fill} \par %插入空行
\textbf{异构系统}

就我们的目的而言，异构系统是指包含多种类型计算设备的系统。例如：同时具有中央处理单元(CPU)和图形处理单元(GPU)的系统是一个异构系统。CPU通常称为处理器，尽管我们将异构系统中的所有处理单元称为计算处理器时，可能会混淆。为了避免这种混淆，SYCL将处理单元称为设备。第2章将开始讨论如何将工作(计算)放到异构系统中的特定设备上。\par

GPU已经成为高性能计算设备，因此有时也称为通用GPU或GPGPU。\par

现在，异构系统中的设备集合可以包括CPU、GPU、FPGA(现场可编程门阵列)、DSP(数字信号处理器)、ASIC(应用专用集成电路)和AI芯片(图形、神经拟态等)。\par

这类设备通常重复涉及计算处理器(多处理器)，以及增加诸如内存等数据源的连接(增加带宽)。第一个是多处理，对于提高吞吐量特别有用。我们的类比中，这通过添加额外的司机和卡车来实现。后者有更高的数据带宽，对于减少延迟特别有用。这些，可以通过使用更多的装载坞来实现，以使卡车能够并行装载。\par

拥有多种类型设备时，每种设备具有不同的架构，因此具有不同的特性，这就导致每种设备需要不同的编程和优化需求。这就成为了编写SYCL(DPC++编译器)的动机，也是本书的主要内容。\par

\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black]
SYCL是为了解决异构系统中数据并行编程的挑战。
\end{tcolorbox}

\hspace*{\fill} \par %插入空行
\textbf{数据并行编程}

数据并行编程关注的是并行性，可以将其想象为一组并行操作的数据。我们需要运送100个包裹(有效地大量数据)，以便将工作分配给100辆有司机的卡车。关键的是我们应该划分什么？处理整个图像，还是用小块，还是逐像素处理？应该将对象的集合分析为单个集合，还是将对象的一组更小的分组，或者一个对象一个对象地分析？\par

选择正确的工作分工并将其有效地映射到计算资源上，是使用SYCL和DPC++的并行开发者的责任。这个主题会在第4章开始讨论。\par












